<?php


namespace Yond\LaravelDomain\Models\Casts;


use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use LogicException;
use Yond\LaravelDomain\Models\Concerns\NestedSet;

class NestedSetField implements CastsAttributes
{
    protected string $relation;
    protected string $field;

    public function __construct($relation, $field = 'id')
    {
        $this->relation = $relation;
        $this->field = $field;
    }

    protected function check($model)
    {
        /** @var BelongsTo $relationship */
        $relationship = $model->{$this->relation}();

        if (!($relationship instanceof BelongsTo)) {
            throw new LogicException('relation '. $this->relation .' must be BelongsTo when use NestedSetField Cast');
        }

        $relationModel = $relationship->getModel();

        if (!in_array(NestedSet::class, class_uses_recursive($relationModel))) {
            throw new LogicException('relation ' . $this->relation . ' Model must use Yond\LaravelDomain\Models\Concerns\NestedSet Trait when use NestedSetField Cast');
        }

    }

    public function get($model, string $key, $value, array $attributes)
    {
        $this->check($model);

        return $model->loadMissing($this->relation . '.ancestors')->{$this->relation}->ancestors->push($model->{$this->relation})->pluck($this->field);
    }

    public function set($model, string $key, $value, array $attributes): array
    {
        $this->check($model);

        if (is_array($value)) {
            /** @var BelongsTo $relationship */
            $relationship = $model->{$this->relation}();
            $foreignKey = $relationship->getForeignKeyName();

            return [$foreignKey => $value[array_key_last($value)]];
        } else {
            return [];
        }
    }
}
